package com.pshare.service;

import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.pshare.enums.PushType;
import com.pshare.sender.BaiduPushSender;
import com.pshare.sender.JpushSender;
import com.pshare.sender.PushSender;
import com.pshare.sender.UmengSender;

/**
 * 推送Service层接口
 */
public abstract class AbstractPushService extends PushSender {
	
	private static final Logger logger = Logger.getLogger(AbstractPushService.class);
	protected Integer lenthCheck = null;
	protected static final Integer IOS_LENGTH = 64;
	
	private static ExecutorService executorService = Executors.newCachedThreadPool();

	protected PushSender androidPushSender;
	
	public AbstractPushService() {
		if (androidPushType == PushType.BAIDU.getCode()) {
			androidPushSender = new BaiduPushSender();
        	lenthCheck = 44;
		} else if (androidPushType == PushType.UMENG.getCode()) {
			androidPushSender = new UmengSender();
        	lenthCheck = 44;
		} else if (androidPushType == PushType.JPUSH.getCode()) {
			androidPushSender = new JpushSender();
        	lenthCheck = 11;
		} else {
			androidPushSender = new BaiduPushSender();
        	lenthCheck = 44;
		}
	}
	
	/**
	 * 对某个用户发送消息
	 * @param userId
	 * @param title 消息标题
	 * @param message 消息内容
	 * @param objId 传递的对象ID
	 * @param type
	 */
	public void push(Long userId, String title, String message, String objId, Integer type) {
		this.push(userId, title, message, objId, type, null);
	}
	
	public void push(Long userId, String title, String message, Integer type) {
		this.push(userId, title, message, null, type, null);
	}
	
	public void push(Long userId, String title, String message, String objId, Integer type, String sound) {
		if (userId == null) {
			logger.warn("userId is null. give up pushing.");
			return;
		}
		if (StringUtils.isBlank(message)) {
			logger.warn("message is blank. give up pushing.");
			return;
		}
		
		executorService.submit(new PushCall(userId, title, message, objId, type, sound));
	}
	
	/**
	 * 对一组用户发送消息
	 * @param userIds
	 * @param message
	 * @param objId 传递对象的ID
	 * @param type
	 * @param sound
	 */
	public void push(List<Long> userIds, String title, String message, String objId, Integer type, String sound) {
		if(userIds == null || userIds.size() == 0) {
			logger.warn("userIds list is null. give up pushing.");
			return;
		}
		if (message == null || message.length() == 0) {
			logger.warn("message is blank. give up pushing.");
			return;
		}
		
		executorService.submit(new PushCall(userIds, title, message, objId, type, sound));
	}
	
	public void push(List<Long> userIds, String title, String message, String objId, Integer type) {
		push(userIds, title, message, objId, type, null);
	}
	
	public void push(List<Long> userIds, String title, String message, Long objId, Integer type) {
		push(userIds, title, message, objId + "", type, null);
	}
	
	public void push(List<Long> userIds, String title, String message, Integer objId, Integer type) {
		push(userIds, title, message, objId + "", type, null);
	}
	
	public void push(List<Long> userIds, String title, String message, Integer type) {
		push(userIds, title, message, null, type, null);
	}
	
	public void pushToAll(String title, String message, String objId) {
		pushToAll(title, message, objId, null);
	}
	
	public void pushToAll(String title, String message) {
		pushToAll(title, message, null, null);
	}
	
	/**
	 * 推送消息给所有人
	 * @param message
	 * @param type
	 */
	public void pushToAll(String title, String message, String objId, Integer type) {
		executorService.submit(new PushCall(title, message, objId, type, null));
	}
	
	private class PushCall implements Callable<String> {
		private Long userId;
		private List<Long> userIds;
		private String title;
		private String message;
		private String objId;
		private Integer type;
		private String sound;
		
		public PushCall(Long userId, String title, String message, String objId, Integer type, String sound) {
			this.userId = userId;
			this.type = type;
			this.sound = sound;
			this.title = title;
			this.objId = objId;
			this.message = message;
		}
		
		public PushCall(List<Long> userIds, String title, String message, String objId, Integer type, String sound) {
			this.userIds = userIds;
			this.type = type;
			this.sound = sound;
			this.title = title;
			this.objId = objId;
			this.message = message;
		}
		
		public PushCall(String title, String message, String objId, Integer type, String sound) {
			this.type = type;
			this.sound = sound;
			this.title = title;
			this.objId = objId;
			this.message = message;
		}
		
//		private void seperateObjId(String message) {
//			if(message.indexOf(SeaxConstants.SEPERATE_STR) > 0) {
//				String[] msgs = message.split(SeaxConstants.SEPERATE_STR);
//				this.message = msgs[0];
//				this.objId = msgs[1];
//			} else {
//				this.message = message;
//			}
//		}
		
		@Override
		public String call() throws Exception {
			if(userIds != null) {
				doPush(userIds, title, message, objId, type, sound);
			} else if (userId != null) {
				doPush(userId, title, message, objId, type, sound);
			} else {
				doPush(title, message, objId, type, sound);
			}
			return "complete";
		}
	}
	
	protected void doPush(String title, String message, String objId, Integer bizType, String sound) {
		broadcast(title, message, objId, bizType, sound);
	}

	protected abstract void doPush(Long userId, String title, String message, String objId, Integer bizType, String sound);
	
	protected abstract void doPush(List<Long> userIds, String title, String message, String objId, Integer bizType, String sound);

	/**
	 * 广播
	 * @param message
	 * @param msgType
	 */
	protected abstract void broadcast(String title, String message, String objId, Integer msgType, String sound);
	
	
	@Override
	@Deprecated
	public void doPush(Integer type, List<String> deviceTokens, String title, String message, String objId, Integer msgType, String sound) {

	}

	protected PushSender getAndroidPushSender() {
		return androidPushSender;
	}
	
}
